package collection.view;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.testng.annotations.Test;

/**
 * 视图
 *
 * 表述1 在Java中，集合视图是一种特殊的集合，它提供对另一个集合的动态视图，所做的更改会立即反映在视图上，反之亦然
 * 表述2 从集合类通过映射关系获取另一个集合类，而非直接创建新集合类。优点是不占用额外空间，缺点是非真实集合，看上去不太直观；
 * 另外，消耗了一定的栈存储空间，不能做太多层的映射，会超出栈内存。
 *
 */
public class MyView {

    public static void main(String[] args) {
        String[] strings = {"a", "b", "c"};

        // 返回一个新的ArrayList对象
        List<String> list = Arrays.asList(strings);

        // "a"
        System.out.println(list.get(0));

        strings[0] = "d";
        // "d"，改变原数组，视图也跟着改变
        System.out.println(list.get(0));

        // 改变view的值，会连带改变原数组
        list.set(0, "e");
        // "e"
        System.out.println(strings[0]);

        // 视图无法添加元素,也无法删除元素,原因是这个list不是寻常的ArrayList而是一个Array.ArrayList,这是一个私有的类,只能通过Array#asList得到
        // 其实如果能够用Array.ArrayList声明对象的话,会发现这个对象根本没有remove和add方法和
        list.remove("e");
        System.out.println("after remove" + list);
    }

    @Test
    private void t1() {
        Integer i = 0;
        var map = new HashMap<Integer, Integer>();
        map.put(1, 1);
        map.put(2, 2);

        var map2 = new HashMap<Integer, Integer>();
        map.put(3, 3);
        map.put(4, 4);

        // 如果只想得到一个集合的视图，不建议使用这个api
        List<HashMap<Integer, Integer>> list = Arrays.asList(map);
        System.out.println(list);

        List<Collection<Integer>> list2 = Arrays.asList(map.values(), map2.values());
        System.out.println(list2);

        List<Set<Integer>> list3 = Collections.singletonList(map.keySet());
        System.out.println(list3);
    }

    @Test
    private void t2() {
        String[] strings = {"a", "b", "c"};

        // 返回一个新的ArrayList对象
        List<String> list = Arrays.asList(strings);

        // "a"
        System.out.println(list.get(0));

        strings[0] = "d";
        // "d"，改变原数组，视图也跟着改变
        System.out.println(list.get(0));

        // 改变view的值，会连带改变原数组
        list.set(0, "e");
        // "e"
        System.out.println(strings[0]);

        // 视图无法添加元素，也无法删除元素
        list.remove("e");
        System.out.println("after remove" + list);
//        list.add("f");

    }


    @Test
    private void t3() {

        String[] str = {"a", "b", "c", "d"};
        var list = Collections.nCopies(3, "view");
        var set = new HashSet<>();
        set.add("v");

        var sorted = new TreeSet<>();
        sorted.add("sorted");
        System.out.println(list);

        // 不可修改视图
//        Collections.unmodifiableCollection(list);
        Collections.unmodifiableList(list);
//        Collections.unmodifiableSet(set);
//        Collections.unmodifiableSortedSet(sorted);
//        Collections.unmodifiableNavigableSet();
//        Collections.unmodifiableMap();
//        Collections.unmodifiableSortedSet(sorted);
//        Collections.unmodifiableNavigableMap();

//        同步视图，线程安全
        List<String> list1 = Collections.synchronizedList(list);

//        受限视图
        ArrayList<String> strings = new ArrayList<>();
        ArrayList rawList = strings;
        rawList.add(0);

        Collections.checkedList(list, String.class);
    }

    @Test
    private void t4() {
        var map = new HashMap<Integer, Integer>();
        map.put(1, 1);
        map.put(2, 2);
        Set<Integer> integers = map.keySet();

    }
}
